using Microsoft.Win32;
using System;
using System.Text;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using SolidWorksTools;
using System.Diagnostics;
using System.Collections.Generic;
using System.IO;

namespace InstallSW
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void ButtonAction(object sender, RoutedEventArgs e)
        {
            Button button = (Button)sender;

            if (button.Name.Equals("selfilebtn"))
            {
                OpenFileDialog sfd = new OpenFileDialog();
                sfd.Filter = "DLL|*.dll";
                sfd.Multiselect = true;
                sfd.ShowDialog();
                string[] filestrs = sfd.FileNames;
                foreach(string filedll in filestrs)
                {
                    if (IsStandartRegisterFile(filedll))
                        this.preRegDllList.Items.Add( CreateListBoxItem(filedll, true) );
                }

            }
            else if (button.Name.Equals("register"))
            {
                string[] dlls = GetListBoxSelectItems(this.preRegDllList);
                if (dlls == null || dlls.Length == 0)
                {
                    MessageBox.Show("请先选中文件");
                    return;
                }
                foreach(string _dll in dlls)
                {
                    Regasm(_dll, true);
                }
                MessageBox.Show("注册成功");
                LoadRegister();
            }
            else if(button.Name.Equals("UNregester"))
            {
                string[] dlls = GetListBoxSelectItems(this.regDllList);
                if (dlls == null || dlls.Length == 0)
                {
                    MessageBox.Show("请先选中文件");
                    return;
                }
                foreach (string _dll in dlls)
                {
                    int result = Regasm(_dll, false);
                    if(result != 1)
                    {
                        MessageBox.Show("卸载失败");
                        return;
                    }
                }
                MessageBox.Show("卸载成功");

                LoadRegister();
            }
        }

        protected void LoadRegister()
        {
            try
            {
                this.regDllList.Items.Clear();

                HashSet<string> fset = new HashSet<string>();
                Microsoft.Win32.RegistryKey hkcu = Microsoft.Win32.Registry.CurrentUser;
                Microsoft.Win32.RegistryKey hkcc = Microsoft.Win32.Registry.ClassesRoot;

                string keyname = "Software\\SolidWorks\\AddInsStartup";
                RegistryKey reg1 = hkcu.OpenSubKey(keyname);

                foreach (string keyval1 in reg1.GetSubKeyNames())
                {
                    StringBuilder keysb = new StringBuilder();
                    keysb.Append("CLSID\\");
                    keysb.Append(keyval1);
                    keysb.Append("\\InprocServer32");

                    keyname = keysb.ToString();
                    RegistryKey reg2 = hkcc.OpenSubKey(keyname);
                    if (reg2 != null)
                    {
                        foreach (string keyval2 in reg2.GetSubKeyNames())
                        {
                            string keypath = keysb.ToString() + "\\" + keyval2;
                            RegistryKey key3 = hkcc.OpenSubKey(keypath);
                            if (key3 != null)
                            {
                                object filepathobj = key3.GetValue("CodeBase");
                                if (filepathobj != null)
                                {
                                    string filepath = filepathobj as string;
                                    filepath = filepath.Substring(filepath.IndexOf("///") + "///".Length);
                                    fset.Add(filepath);
                                }
                            }
                        }
                    }
                }

                hkcu.Close();
                hkcc.Close();

                foreach (string filedll in fset)
                {
                    if (IsStandartRegisterFile(filedll))
                        this.regDllList.Items.Add(CreateListBoxItem(filedll, false));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            LoadRegister();
            
        }

        protected bool IsStandartRegisterFile(string filedll)
        {
            if (File.Exists(filedll))
            {
                Assembly assembly = Assembly.LoadFile(filedll);
                foreach (CustomAttributeData catrr in assembly.CustomAttributes)
                {
                    foreach (CustomAttributeTypedArgument cata in catrr.ConstructorArguments)
                    {
                        string cataStr = cata.Value as string;
                        if (cataStr == "SOLIDWORDS")
                        {
                            return true;
                        }
                    }

                }
            }

            return false;
        }

        protected ListBoxItem CreateListBoxItem(string path, bool isCheck)
        {
            ListBoxItem listboxitem = new ListBoxItem();
            CheckBox checkbox = new CheckBox();
            checkbox.IsChecked = isCheck;
            checkbox.Content = path;
            listboxitem.Content = checkbox;
            return listboxitem;
        }

        protected string[] GetListBoxSelectItems(ListBox listbox)
        {
            List<string> selStrs = new List<string>();
            foreach(ListBoxItem listboxitem in listbox.Items)
            {
                object conObj = listboxitem.Content;
                CheckBox checkbox = conObj as CheckBox;
                if (checkbox.IsChecked.Value)
                {
                    selStrs.Add(checkbox.Content.ToString());
                }
            }

            return selStrs.ToArray();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="targetpath"></param>
        /// <param name="isRegist"> if true do regist else do unregist</param>
        protected int Regasm(string targetpath, bool isRegist)
        {
            try
            {
                if (File.Exists(targetpath))
                {
                    Assembly assembly = Assembly.LoadFile(targetpath);
                    string FMWK = assembly.ImageRuntimeVersion;
                    
                    StringBuilder cmdsb = new StringBuilder();
                    cmdsb.Append(@"C:\Windows\Microsoft.NET\Framework64\");
                    cmdsb.Append(FMWK);
                    cmdsb.Append(@"\regasm ");
                    if(!isRegist)
                    {
                        cmdsb.Append(" /unregister");
                    }
                    cmdsb.Append("  /codebase");
                    cmdsb.Append("  \"" + targetpath + "\"");
                    cmdsb.Append(" &exit");
                    //cmdsb.Append("  " + targetpath );

                    Process pro = new Process();
                    pro.StartInfo.FileName = "cmd.exe";
                    pro.StartInfo.UseShellExecute = false;
                    pro.StartInfo.RedirectStandardInput = true;
                    pro.StartInfo.RedirectStandardOutput = true;
                    pro.StartInfo.RedirectStandardError = true;
                    pro.StartInfo.CreateNoWindow = false;
                    pro.Start();

                    pro.StandardInput.WriteLine(cmdsb.ToString());
                    pro.StandardInput.AutoFlush = true;

                    //string output = pro.StandardOutput.ReadToEnd();

                    pro.WaitForExit();
                    pro.Close();

                    return 1;
                }
                
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
                return -1;
            }


            return 0;
        }



    }
}
